package org.aceor.mddal.atom;

import org.aceor.mddal.atom.adapter.AbstractAtomStatementAdapter;
import org.aceor.mddal.common.monitor.Monitor;
import org.aceor.mddal.common.monitor.MonitorPoint;
import org.aceor.mddal.common.sqlparser.util.SQLCommonUtil;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * Created by lxue on 16/3/27.
 */
public class AtomStatementWrapper extends AbstractAtomStatementAdapter implements Statement {

    public AtomStatementWrapper(Statement targetStatement, Connection atomConnectionWrapper) {
        super(targetStatement, atomConnectionWrapper);
    }

    @Override
    public int executeUpdate(String sql) throws SQLException {
        return executeUpdateInternal(sql, -1, null, null);
    }

    @Override
    public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
        return executeUpdateInternal(sql, autoGeneratedKeys, null, null);
    }

    @Override
    public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
        return executeUpdateInternal(sql, -1, columnIndexes, null);
    }

    @Override
    public int executeUpdate(String sql, String[] columnNames) throws SQLException {
        return executeUpdateInternal(sql, -1, null, columnNames);
    }

    @Override
    public ResultSet executeQuery(String sql) throws SQLException {
        Monitor.startSqlExecuteMonitor(sql);
        try {
            return targetStatement.executeQuery(sql);
        } finally {
            Monitor.stop(MonitorPoint.EXECUTE_SQL);
        }
    }

    @Override
    public boolean execute(String sql, int[] columnIndexes) throws SQLException {
        return executeInternal(sql, -1, columnIndexes, null);
    }

    @Override
    public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
        return executeInternal(sql, autoGeneratedKeys, null, null);
    }

    @Override
    public boolean execute(String sql, String[] columnNames) throws SQLException {
        return executeInternal(sql, -1, null, columnNames);
    }

    public boolean execute(String sql) throws SQLException {
        return executeInternal(sql, -1, null, null);
    }

    private boolean executeInternal(String sql, int autoGeneratedKeys, int[] columnIndexes, String[] columnNames)
            throws SQLException {
        if (SQLCommonUtil.isQuerySql(sql)) {
            executeQuery(sql);
            return true;
        } else {
            executeUpdateInternal(sql, autoGeneratedKeys, columnIndexes, columnNames);
            return false;
        }
    }

    private int executeUpdateInternal(String sql, int autoGeneratedKeys, int[] columnIndexes, String[] columnNames) throws SQLException {
        Monitor.startSqlExecuteMonitor(sql);
        try {
            if (autoGeneratedKeys == -1 && columnIndexes == null && columnNames == null) {
                return targetStatement.executeUpdate(sql);
            } else if (autoGeneratedKeys != -1) {
                return targetStatement.executeUpdate(sql, autoGeneratedKeys);
            } else if (columnIndexes != null) {
                return targetStatement.executeUpdate(sql, columnIndexes);
            } else if (columnNames != null) {
                return targetStatement.executeUpdate(sql, columnNames);
            } else {
                return targetStatement.executeUpdate(sql);
            }
        } catch (SQLException e) {
            //TODO: LOG
            throw e;
        } finally {
            Monitor.stop(MonitorPoint.EXECUTE_SQL);
        }
    }
}
